/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

// THIS FILE IS GENERATED BY ZAP

#include "gen/CHIPClientCallbacks.h"

#include <cinttypes>

#include <app/Command.h>
#include <app/common/gen/enums.h>
#include <app/util/CHIPDeviceCallbacksMgr.h>
#include <app/util/af-enums.h>
#include <app/util/af.h>
#include <app/util/attribute-list-byte-span.h>
#include <app/util/basic-types.h>
#include <core/CHIPEncoding.h>
#include <support/BytesToHex.h>
#include <support/SafeInt.h>
#include <support/logging/CHIPLogging.h>

using namespace ::chip;
using namespace ::chip::app::List;

constexpr uint16_t kByteSpanSizeLengthInBytes = 2;

#define CHECK_STATUS_WITH_RETVAL(error, retval)                                                                                    \
    if (CHIP_NO_ERROR != error)                                                                                                    \
    {                                                                                                                              \
        ChipLogError(Zcl, "CHECK_STATUS %s", ErrorStr(error));                                                                     \
        if (onFailureCallback != nullptr)                                                                                          \
        {                                                                                                                          \
            Callback::Callback<DefaultFailureCallback> * cb =                                                                      \
                Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);                                     \
            cb->mCall(cb->mContext, static_cast<uint8_t>(EMBER_ZCL_STATUS_INVALID_VALUE));                                         \
        }                                                                                                                          \
        return retval;                                                                                                             \
    }

#define CHECK_STATUS(error) CHECK_STATUS_WITH_RETVAL(error, true)
#define CHECK_STATUS_VOID(error) CHECK_STATUS_WITH_RETVAL(error, )

#define CHECK_MESSAGE_LENGTH_WITH_RETVAL(value, retval)                                                                            \
    if (!chip::CanCastTo<uint16_t>(value))                                                                                         \
    {                                                                                                                              \
        ChipLogError(Zcl, "CHECK_MESSAGE_LENGTH expects a uint16_t value, got: %d", value);                                        \
        if (onFailureCallback != nullptr)                                                                                          \
        {                                                                                                                          \
            Callback::Callback<DefaultFailureCallback> * cb =                                                                      \
                Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);                                     \
            cb->mCall(cb->mContext, static_cast<uint8_t>(EMBER_ZCL_STATUS_INVALID_VALUE));                                         \
        }                                                                                                                          \
        return retval;                                                                                                             \
    }                                                                                                                              \
                                                                                                                                   \
    if (messageLen < value)                                                                                                        \
    {                                                                                                                              \
        ChipLogError(Zcl, "Unexpected response length: %d", messageLen);                                                           \
        if (onFailureCallback != nullptr)                                                                                          \
        {                                                                                                                          \
            Callback::Callback<DefaultFailureCallback> * cb =                                                                      \
                Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);                                     \
            cb->mCall(cb->mContext, static_cast<uint8_t>(EMBER_ZCL_STATUS_INVALID_VALUE));                                         \
        }                                                                                                                          \
        return retval;                                                                                                             \
    }                                                                                                                              \
                                                                                                                                   \
    messageLen = static_cast<uint16_t>(messageLen - static_cast<uint16_t>(value));

#define CHECK_MESSAGE_LENGTH(value) CHECK_MESSAGE_LENGTH_WITH_RETVAL(value, true)
#define CHECK_MESSAGE_LENGTH_VOID(value) CHECK_MESSAGE_LENGTH_WITH_RETVAL(value, )

#define GET_RESPONSE_CALLBACKS(name)                                                                                               \
    Callback::Cancelable * onSuccessCallback = nullptr;                                                                            \
    Callback::Cancelable * onFailureCallback = nullptr;                                                                            \
    NodeId sourceId                          = emberAfCurrentCommand()->SourceNodeId();                                            \
    uint8_t sequenceNumber                   = emberAfCurrentCommand()->seqNum;                                                    \
    CHIP_ERROR err = gCallbacks.GetResponseCallback(sourceId, sequenceNumber, &onSuccessCallback, &onFailureCallback);             \
                                                                                                                                   \
    if (CHIP_NO_ERROR != err)                                                                                                      \
    {                                                                                                                              \
        if (onSuccessCallback == nullptr)                                                                                          \
        {                                                                                                                          \
            ChipLogDetail(Zcl, "%s: Missing success callback", name);                                                              \
        }                                                                                                                          \
                                                                                                                                   \
        if (onFailureCallback == nullptr)                                                                                          \
        {                                                                                                                          \
            ChipLogDetail(Zcl, "%s: Missing failure callback", name);                                                              \
        }                                                                                                                          \
                                                                                                                                   \
        return true;                                                                                                               \
    }

#define GET_CLUSTER_RESPONSE_CALLBACKS(name)                                                                                       \
    Callback::Cancelable * onSuccessCallback = nullptr;                                                                            \
    Callback::Cancelable * onFailureCallback = nullptr;                                                                            \
    NodeId sourceIdentifier                  = reinterpret_cast<NodeId>(commandObj);                                               \
    /* #6559: Currently, we only have one commands for the IMInvokeCommands and to a device, so the seqNum is always set to 0. */  \
    CHIP_ERROR err = gCallbacks.GetResponseCallback(sourceIdentifier, 0, &onSuccessCallback, &onFailureCallback);                  \
                                                                                                                                   \
    if (CHIP_NO_ERROR != err)                                                                                                      \
    {                                                                                                                              \
        if (onSuccessCallback == nullptr)                                                                                          \
        {                                                                                                                          \
            ChipLogDetail(Zcl, "%s: Missing success callback", name);                                                              \
        }                                                                                                                          \
                                                                                                                                   \
        if (onFailureCallback == nullptr)                                                                                          \
        {                                                                                                                          \
            ChipLogDetail(Zcl, "%s: Missing failure callback", name);                                                              \
        }                                                                                                                          \
                                                                                                                                   \
        return true;                                                                                                               \
    }

#define GET_REPORT_CALLBACK(name)                                                                                                  \
    Callback::Cancelable * onReportCallback = nullptr;                                                                             \
    CHIP_ERROR err = gCallbacks.GetReportCallback(sourceId, endpointId, clusterId, attributeId, &onReportCallback);                \
                                                                                                                                   \
    if (CHIP_NO_ERROR != err)                                                                                                      \
    {                                                                                                                              \
        if (onReportCallback == nullptr)                                                                                           \
        {                                                                                                                          \
            ChipLogDetail(Zcl, "%s: Missing report callback", name);                                                               \
        }                                                                                                                          \
                                                                                                                                   \
        return true;                                                                                                               \
    }

void LogStatus(uint8_t status)
{
    switch (status)
    {
    case EMBER_ZCL_STATUS_SUCCESS:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_SUCCESS (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_FAILURE:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_FAILURE (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_NOT_AUTHORIZED:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_NOT_AUTHORIZED (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_MALFORMED_COMMAND:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_MALFORMED_COMMAND (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_UNSUP_COMMAND:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_UNSUP_CLUSTER_COMMAND (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_UNSUP_GENERAL_COMMAND:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_UNSUP_GENERAL_COMMAND (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_UNSUP_MANUF_CLUSTER_COMMAND:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_UNSUP_MANUF_CLUSTER_COMMAND (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_UNSUP_MANUF_GENERAL_COMMAND:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_UNSUP_MANUF_GENERAL_COMMAND (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_INVALID_FIELD:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_INVALID_FIELD (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_INVALID_VALUE:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_INVALID_VALUE (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_READ_ONLY:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_READ_ONLY (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_INSUFFICIENT_SPACE:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_INSUFFICIENT_SPACE (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_DUPLICATE_EXISTS:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_DUPLICATE_EXISTS (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_NOT_FOUND:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_NOT_FOUND (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_UNREPORTABLE_ATTRIBUTE:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_UNREPORTABLE_ATTRIBUTE (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_INVALID_DATA_TYPE:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_INVALID_DATA_TYPE (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_INVALID_SELECTOR:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_INVALID_SELECTOR (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_WRITE_ONLY:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_WRITE_ONLY (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_INCONSISTENT_STARTUP_STATE:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_INCONSISTENT_STARTUP_STATE (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_DEFINED_OUT_OF_BAND:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_DEFINED_OUT_Of_BAND (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_ACTION_DENIED:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_ACTION_DENIED (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_TIMEOUT:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_TIMEOUT (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_ABORT:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_ABORT (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_INVALID_IMAGE:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_INVALID_IMAGE (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_WAIT_FOR_DATA:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_WAIT_FOR_DATA (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_NO_IMAGE_AVAILABLE:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_NO_IMAGE_AVAILABLE (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_REQUIRE_MORE_IMAGE:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_REQUIRE_MORE_IMAGE (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_HARDWARE_FAILURE:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_HARDWARE_FAILURE (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_SOFTWARE_FAILURE:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_SOFTWARE_FAILURE (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_UNSUPPORTED_CLUSTER:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_UNSUPPORTED_CLUSTER (0x%02x)", status);
        break;
    case EMBER_ZCL_STATUS_LIMIT_REACHED:
        ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_LIMIT_REACHED (0x%02x)", status);
        break;
    default:
        ChipLogError(Zcl, "Unknow status: 0x%02x", status);
        break;
    }
}

static void LogIMStatus(Protocols::InteractionModel::ProtocolCode status)
{
    switch (status)
    {
    case Protocols::InteractionModel::ProtocolCode::Success:
        ChipLogProgress(Zcl, "  status: Success                (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Failure:
        ChipLogProgress(Zcl, "  status: Failure                (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::InvalidSubscription:
        ChipLogProgress(Zcl, "  status: InvalidSubscription    (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::UnsupportedAccess:
        ChipLogProgress(Zcl, "  status: UnsupportedAccess      (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::UnsupportedEndpoint:
        ChipLogProgress(Zcl, "  status: UnsupportedEndpoint    (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::InvalidAction:
        ChipLogProgress(Zcl, "  status: InvalidAction          (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::UnsupportedCommand:
        ChipLogProgress(Zcl, "  status: UnsupportedCommand     (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reserved82:
        ChipLogProgress(Zcl, "  status: Reserved82             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reserved83:
        ChipLogProgress(Zcl, "  status: Reserved83             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reserved84:
        ChipLogProgress(Zcl, "  status: Reserved84             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::InvalidCommand:
        ChipLogProgress(Zcl, "  status: InvalidCommand         (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::UnsupportedAttribute:
        ChipLogProgress(Zcl, "  status: UnsupportedAttribute   (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::InvalidValue:
        ChipLogProgress(Zcl, "  status: InvalidValue           (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::UnsupportedWrite:
        ChipLogProgress(Zcl, "  status: UnsupportedWrite       (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::ResourceExhausted:
        ChipLogProgress(Zcl, "  status: ResourceExhausted      (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reserved8a:
        ChipLogProgress(Zcl, "  status: Reserved8a             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::NotFound:
        ChipLogProgress(Zcl, "  status: NotFound               (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::UnreportableAttribute:
        ChipLogProgress(Zcl, "  status: UnreportableAttribute  (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::InvalidDataType:
        ChipLogProgress(Zcl, "  status: InvalidDataType        (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reserved8e:
        ChipLogProgress(Zcl, "  status: Reserved8e             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::UnsupportedRead:
        ChipLogProgress(Zcl, "  status: UnsupportedRead        (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reserved90:
        ChipLogProgress(Zcl, "  status: Reserved90             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reserved91:
        ChipLogProgress(Zcl, "  status: Reserved91             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reserved92:
        ChipLogProgress(Zcl, "  status: Reserved92             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reserved93:
        ChipLogProgress(Zcl, "  status: Reserved93             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Timeout:
        ChipLogProgress(Zcl, "  status: Timeout                (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reserved95:
        ChipLogProgress(Zcl, "  status: Reserved95             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reserved96:
        ChipLogProgress(Zcl, "  status: Reserved96             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reserved97:
        ChipLogProgress(Zcl, "  status: Reserved97             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reserved98:
        ChipLogProgress(Zcl, "  status: Reserved98             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reserved99:
        ChipLogProgress(Zcl, "  status: Reserved99             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reserved9a:
        ChipLogProgress(Zcl, "  status: Reserved9a             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::ConstraintError:
        ChipLogProgress(Zcl, "  status: ConstraintError        (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Busy:
        ChipLogProgress(Zcl, "  status: Busy                   (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reservedc0:
        ChipLogProgress(Zcl, "  status: Reservedc0             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reservedc1:
        ChipLogProgress(Zcl, "  status: Reservedc1             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reservedc2:
        ChipLogProgress(Zcl, "  status: Reservedc2             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::UnsupportedCluster:
        ChipLogProgress(Zcl, "  status: UnsupportedCluster     (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::Reservedc4:
        ChipLogProgress(Zcl, "  status: Reservedc4             (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::NoUpstreamSubscription:
        ChipLogProgress(Zcl, "  status: NoUpstreamSubscription (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    case Protocols::InteractionModel::ProtocolCode::InvalidArgument:
        ChipLogProgress(Zcl, "  status: InvalidArgument        (0x%04" PRIx16 ")", Protocols::InteractionModel::ToUint16(status));
        break;
    default:
        ChipLogError(Zcl, "Unknown status: 0x%04" PRIx16, Protocols::InteractionModel::ToUint16(status));
        break;
    }
}

void LogStringAttribute(const uint8_t * string, const uint32_t length, const bool isHumanReadable)
{
    if (isHumanReadable)
    {
        ChipLogProgress(Zcl, "  value: %.*s", length, string);
        return;
    }

    char buffer[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE];
    if (CHIP_NO_ERROR == Encoding::BytesToUppercaseHexString(&string[0], length, &buffer[0], CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE))
    {
        ChipLogProgress(Zcl, "  value: %s", buffer);
    }
}

// Singleton instance of the callbacks manager
app::CHIPDeviceCallbacksMgr & gCallbacks = app::CHIPDeviceCallbacksMgr::GetInstance();

bool emberAfDefaultResponseCallback(ClusterId clusterId, CommandId commandId, EmberAfStatus status)
{
    ChipLogProgress(Zcl, "DefaultResponse:");
    ChipLogProgress(Zcl, "  ClusterId: 0x%08x", clusterId);
    ChipLogProgress(Zcl, "  CommandId: 0x%08x", commandId);
    LogStatus(status);

    GET_RESPONSE_CALLBACKS("emberAfDefaultResponseCallback");
    if (status == EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultSuccessCallback> * cb =
            Callback::Callback<DefaultSuccessCallback>::FromCancelable(onSuccessCallback);
        cb->mCall(cb->mContext);
    }
    else
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, static_cast<uint8_t>(status));
    }

    return true;
}

bool IMDefaultResponseCallback(const chip::app::Command * commandObj, EmberAfStatus status)
{
    ChipLogProgress(Zcl, "DefaultResponse:");
    ChipLogProgress(Zcl, "  Transaction: %p", commandObj);
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("emberAfDefaultResponseCallback");
    if (status == EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultSuccessCallback> * cb =
            Callback::Callback<DefaultSuccessCallback>::FromCancelable(onSuccessCallback);
        cb->mCall(cb->mContext);
    }
    else
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, static_cast<uint8_t>(status));
    }

    return true;
}

template <>
void BasicAttributeFilter<StringAttributeCallback>(chip::TLV::TLVReader * data, chip::Callback::Cancelable * onSuccess,
                                                   chip::Callback::Cancelable * onFailure)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    const uint8_t * val;
    uint32_t len;

    if (data->GetType() != chip::TLV::kTLVType_ByteString && data->GetType() != chip::TLV::kTLVType_UTF8String)
    {
        err = CHIP_ERROR_INVALID_ARGUMENT;
    }
    else
    {
        err = data->GetDataPtr(val);
        len = data->GetLength();
    }

    if (CHIP_NO_ERROR == err)
    {
        LogStringAttribute(val, len, data->GetType() == chip::TLV::kTLVType_UTF8String);

        chip::Callback::Callback<StringAttributeCallback> * cb =
            chip::Callback::Callback<StringAttributeCallback>::FromCancelable(onSuccess);
        cb->mCall(cb->mContext, chip::ByteSpan(val, len));
    }
    else
    {
        chip::Callback::Callback<DefaultFailureCallback> * cb =
            chip::Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailure);
        cb->mCall(cb->mContext, EMBER_ZCL_STATUS_INVALID_VALUE);
    }
}

bool IMReadReportAttributesResponseCallback(const app::ReadClient * apReadClient, const app::ClusterInfo & aPath,
                                            TLV::TLVReader * apData, Protocols::InteractionModel::ProtocolCode status)
{
    ChipLogProgress(Zcl, "ReadAttributesResponse:");
    ChipLogProgress(Zcl, "  ClusterId: 0x%04x", aPath.mClusterId);

    Callback::Cancelable * onSuccessCallback = nullptr;
    Callback::Cancelable * onFailureCallback = nullptr;
    app::TLVDataFilter tlvFilter             = nullptr;
    NodeId sourceId                          = aPath.mNodeId;
    // In CHIPClusters.cpp, we are using sequenceNumber as application identifier.
    uint8_t sequenceNumber = static_cast<uint8_t>(apReadClient->GetAppIdentifier());
    CHIP_ERROR err = gCallbacks.GetResponseCallback(sourceId, sequenceNumber, &onSuccessCallback, &onFailureCallback, &tlvFilter);

    if (CHIP_NO_ERROR != err)
    {
        if (onSuccessCallback == nullptr)
        {
            ChipLogDetail(Zcl, "%s: Missing success callback", __FUNCTION__);
        }

        if (onFailureCallback == nullptr)
        {
            ChipLogDetail(Zcl, "%s: Missing failure callback", __FUNCTION__);
        }

        if (tlvFilter == nullptr)
        {
            ChipLogDetail(Zcl, "%s: Missing TLV Data Filter", __FUNCTION__);
        }
        return true;
    }

    chip::AttributeId attributeId = aPath.mFieldId; // attribId
    ChipLogProgress(Zcl, "  attributeId: 0x%04x", attributeId);
    LogIMStatus(status);

    if (status == Protocols::InteractionModel::ProtocolCode::Success && apData != nullptr)
    {
        chip::TLV::TLVType attributeType = apData->GetType();
        ChipLogProgress(Zcl, "  attribute TLV Type: 0x%02x", attributeType);
        tlvFilter(apData, onSuccessCallback, onFailureCallback);
    }
    else
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        // TODO: Should change failure callbacks to accept uint16 status code.
        cb->mCall(cb->mContext, static_cast<uint8_t>(Protocols::InteractionModel::ToUint16(status)));
    }

    return true;
}

bool emberAfWriteAttributesResponseCallback(ClusterId clusterId, uint8_t * message, uint16_t messageLen)
{
    ChipLogProgress(Zcl, "WriteAttributesResponse:");
    ChipLogProgress(Zcl, "  ClusterId: 0x%08x", clusterId);

    GET_RESPONSE_CALLBACKS("emberAfWriteAttributesResponseCallback");

    // struct writeAttributeResponseRecord[]
    while (messageLen)
    {
        CHECK_MESSAGE_LENGTH(1);
        uint8_t status = chip::Encoding::Read8(message); // zclStatus
        LogStatus(status);

        if (status == EMBER_ZCL_STATUS_SUCCESS)
        {
            Callback::Callback<DefaultSuccessCallback> * cb =
                Callback::Callback<DefaultSuccessCallback>::FromCancelable(onSuccessCallback);
            cb->mCall(cb->mContext);
        }
        else
        {
            CHECK_MESSAGE_LENGTH(4);
            AttributeId attributeId = chip::Encoding::LittleEndian::Read32(message); // attribId
            ChipLogProgress(Zcl, "  attributeId: 0x%08x", attributeId);

            Callback::Callback<DefaultFailureCallback> * cb =
                Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
            cb->mCall(cb->mContext, status);
        }

        // The current code is written matching the current API where there is a single attribute written
        // per write command. So if multiple attributes are written at the same time, something is wrong
        // somewhere.
        if (messageLen)
        {
            ChipLogError(Zcl, "Multiple attributes written at the same time. Something went wrong.");
            break;
        }
    }

    return true;
}

bool emberAfConfigureReportingResponseCallback(ClusterId clusterId, uint8_t * message, uint16_t messageLen)
{
    ChipLogProgress(Zcl, "ConfigureReportingResponseCallback:");
    ChipLogProgress(Zcl, "  ClusterId: 0x%08x", clusterId);

    GET_RESPONSE_CALLBACKS("emberAfConfigureReportingResponseCallback");

    // struct configureReportingResponseRecord[]
    while (messageLen)
    {
        CHECK_MESSAGE_LENGTH(1);
        uint8_t status = chip::Encoding::Read8(message); // zclStatus
        LogStatus(status);

        if (status == EMBER_ZCL_STATUS_SUCCESS)
        {
            Callback::Callback<DefaultSuccessCallback> * cb =
                Callback::Callback<DefaultSuccessCallback>::FromCancelable(onSuccessCallback);
            cb->mCall(cb->mContext);
        }
        else
        {
            CHECK_MESSAGE_LENGTH(1);
            uint8_t direction = chip::Encoding::Read8(message); // reportingRole
            ChipLogProgress(Zcl, "  direction: 0x%02x", direction);

            CHECK_MESSAGE_LENGTH(4);
            AttributeId attributeId = chip::Encoding::LittleEndian::Read32(message); // attribId
            ChipLogProgress(Zcl, "  attributeId: 0x%08x", attributeId);

            Callback::Callback<DefaultFailureCallback> * cb =
                Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
            cb->mCall(cb->mContext, status);
        }

        // The current code is written matching the current API where there is a single attribute report
        // per configure command. So if multiple attributes are configured at the same time, something is wrong
        // somewhere.
        if (messageLen)
        {
            ChipLogError(Zcl, "Multiple attributes reports configured at the same time. Something went wrong.");
            break;
        }
    }

    return true;
}

bool emberAfReadReportingConfigurationResponseCallback(chip::ClusterId clusterId, uint8_t * message, uint16_t messageLen)
{
    ChipLogProgress(Zcl, "ReadReportingConfigurationResponse:");
    ChipLogProgress(Zcl, "  ClusterId: 0x%08x", clusterId);

    GET_RESPONSE_CALLBACKS("emberAfReadReportingConfigurationResponseCallback");

    // struct readReportingConfigurationResponseRecord[]
    while (messageLen)
    {
        CHECK_MESSAGE_LENGTH(1);
        uint8_t direction = chip::Encoding::Read8(message); // reportingRole
        ChipLogProgress(Zcl, "  direction: 0x%02x", direction);

        CHECK_MESSAGE_LENGTH(4);
        AttributeId attributeId = chip::Encoding::LittleEndian::Read32(message); // attribId
        ChipLogProgress(Zcl, "  attributeId: 0x%08x", attributeId);

        if (direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED)
        {
            CHECK_MESSAGE_LENGTH(1);
            uint8_t attributeType = chip::Encoding::Read8(message); // zclType
            ChipLogProgress(Zcl, "  attributeType: 0x%02x", attributeType);

            CHECK_MESSAGE_LENGTH(2);
            uint16_t minimumReportingInterval = chip::Encoding::LittleEndian::Read16(message); // uint16
            ChipLogProgress(Zcl, "  minimumReportingInterval: %" PRIu16, minimumReportingInterval);

            CHECK_MESSAGE_LENGTH(2);
            uint16_t maximumReportingInterval = chip::Encoding::LittleEndian::Read16(message); // uint16
            ChipLogProgress(Zcl, "  maximumReportingInterval: %" PRIu16, maximumReportingInterval);

            // FIXME: unk is not supported yet.

            Callback::Callback<ReadReportingConfigurationReportedCallback> * cb =
                Callback::Callback<ReadReportingConfigurationReportedCallback>::FromCancelable(onSuccessCallback);
            cb->mCall(cb->mContext, minimumReportingInterval, maximumReportingInterval);
        }
        else
        {
            CHECK_MESSAGE_LENGTH(2);
            uint16_t timeout = chip::Encoding::LittleEndian::Read16(message); // uint16
            ChipLogProgress(Zcl, "  timeout: %" PRIu16, timeout);

            Callback::Callback<ReadReportingConfigurationReceivedCallback> * cb =
                Callback::Callback<ReadReportingConfigurationReceivedCallback>::FromCancelable(onSuccessCallback);
            cb->mCall(cb->mContext, timeout);
        }
    }

    return true;
}

bool emberAfDiscoverAttributesResponseCallback(ClusterId clusterId, bool discoveryComplete, uint8_t * message, uint16_t messageLen,
                                               bool extended)
{
    ChipLogProgress(Zcl, "DiscoverAttributesResponse:");
    ChipLogProgress(Zcl, "  ClusterId: 0x%08x", clusterId);
    ChipLogProgress(Zcl, "  discoveryComplete: %d", discoveryComplete);
    ChipLogProgress(Zcl, "  extended: %d", extended);

    GET_RESPONSE_CALLBACKS("emberAfDiscoverAttributesCallback");

    // struct discoverAttributesResponseRecord[]
    while (messageLen)
    {
        CHECK_MESSAGE_LENGTH(4);
        AttributeId attributeId = chip::Encoding::LittleEndian::Read32(message); // attribId
        ChipLogProgress(Zcl, "  attributeId: 0x%08x", attributeId);

        CHECK_MESSAGE_LENGTH(1);
        uint8_t attributeType = chip::Encoding::Read8(message); // zclType
        ChipLogProgress(Zcl, "  attributeType: 0x%02x", attributeType);
    }

    Callback::Callback<DefaultSuccessCallback> * cb = Callback::Callback<DefaultSuccessCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfDiscoverCommandsGeneratedResponseCallback(ClusterId clusterId, uint16_t manufacturerCode, bool discoveryComplete,
                                                      CommandId * commandIds, uint16_t commandIdCount)
{
    ChipLogProgress(Zcl, "DiscoverCommandsGeneratedResponse:");
    ChipLogProgress(Zcl, "  ClusterId: 0x%08x", clusterId);
    ChipLogProgress(Zcl, "  manufacturerCode: 0x%04x", manufacturerCode);
    ChipLogProgress(Zcl, "  discoveryComplete: %d", discoveryComplete);
    ChipLogProgress(Zcl, "  commandIdCount: %" PRIu16, commandIdCount);

    for (uint16_t i = 0; i < commandIdCount; i++)
    {
        ChipLogProgress(Zcl, "  commandId: 0x%08x", *commandIds++);
    }

    GET_RESPONSE_CALLBACKS("emberAfDiscoverCommandsGeneratedResponseCallback");
    Callback::Callback<DefaultSuccessCallback> * cb = Callback::Callback<DefaultSuccessCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfDiscoverCommandsReceivedResponseCallback(ClusterId clusterId, uint16_t manufacturerCode, bool discoveryComplete,
                                                     CommandId * commandIds, uint16_t commandIdCount)
{
    ChipLogProgress(Zcl, "DiscoverCommandsReceivedResponse:");
    ChipLogProgress(Zcl, "  ClusterId: 0x%08x", clusterId);
    ChipLogProgress(Zcl, "  manufacturerCode: 0x%04x", manufacturerCode);
    ChipLogProgress(Zcl, "  discoveryComplete: %d", discoveryComplete);
    ChipLogProgress(Zcl, "  commandIdCount: %" PRIu16, commandIdCount);

    for (uint16_t i = 0; i < commandIdCount; i++)
    {
        ChipLogProgress(Zcl, "  commandId: 0x%08x", *commandIds++);
    }

    GET_RESPONSE_CALLBACKS("emberAfDiscoverCommandsGeneratedResponseCallback");
    Callback::Callback<DefaultSuccessCallback> * cb = Callback::Callback<DefaultSuccessCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

static EmberAfStatus PrepareListFromTLV(TLV::TLVReader * tlvData, const uint8_t *& message, uint16_t & messageLen)
{
    CHIP_ERROR tlvError = CHIP_NO_ERROR;
    TLV::TLVReader reader;
    TLV::TLVType type;
    reader.Init(*tlvData);
    reader.EnterContainer(type);
    tlvError = reader.Next();
    if (tlvError != CHIP_NO_ERROR && tlvError != CHIP_END_OF_TLV && chip::CanCastTo<uint16_t>(reader.GetLength()))
    {
        return EMBER_ZCL_STATUS_INVALID_VALUE;
    }
    if (tlvError == CHIP_NO_ERROR)
    {
        tlvError   = reader.GetDataPtr(message);
        messageLen = static_cast<uint16_t>(reader.GetLength());
    }
    if (tlvError != CHIP_NO_ERROR)
    {
        return EMBER_ZCL_STATUS_INVALID_VALUE;
    }
    reader.ExitContainer(type);
    return EMBER_ZCL_STATUS_SUCCESS;
}

void ApplicationLauncherClusterApplicationLauncherListListAttributeFilter(TLV::TLVReader * tlvData,
                                                                          Callback::Cancelable * onSuccessCallback,
                                                                          Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    uint16_t data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(2);
        data[i] = emberAfGetInt16u(message, 0, 2);
        message += 2;
    }
    Callback::Callback<ApplicationLauncherApplicationLauncherListListAttributeCallback> * cb =
        Callback::Callback<ApplicationLauncherApplicationLauncherListListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void AudioOutputClusterAudioOutputListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    _AudioOutputInfo data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].index = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].outputType = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_STATUS_VOID(ReadByteSpan(message, 34, &data[i].name));
        messageLen = static_cast<uint16_t>(messageLen - 34);
        message += 34;
    }
    Callback::Callback<AudioOutputAudioOutputListListAttributeCallback> * cb =
        Callback::Callback<AudioOutputAudioOutputListListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void ContentLauncherClusterAcceptsHeaderListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback,
                                                                Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    chip::ByteSpan data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_STATUS_VOID(ReadByteSpan(message, messageLen, &data[i]));
        uint16_t entryLength = static_cast<uint16_t>(data[i].size() + kByteSpanSizeLengthInBytes);
        messageLen           = static_cast<uint16_t>(messageLen - entryLength);
        message += entryLength;
    }
    Callback::Callback<ContentLauncherAcceptsHeaderListListAttributeCallback> * cb =
        Callback::Callback<ContentLauncherAcceptsHeaderListListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void ContentLauncherClusterSupportedStreamingTypesListAttributeFilter(TLV::TLVReader * tlvData,
                                                                      Callback::Cancelable * onSuccessCallback,
                                                                      Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    uint8_t data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i] = emberAfGetInt8u(message, 0, 1);
        message += 1;
    }
    Callback::Callback<ContentLauncherSupportedStreamingTypesListAttributeCallback> * cb =
        Callback::Callback<ContentLauncherSupportedStreamingTypesListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void DescriptorClusterDeviceListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    _DeviceType data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(4);
        data[i].type = emberAfGetInt32u(message, 0, 4);
        message += 4;
        CHECK_MESSAGE_LENGTH_VOID(2);
        data[i].revision = emberAfGetInt16u(message, 0, 2);
        message += 2;
    }
    Callback::Callback<DescriptorDeviceListListAttributeCallback> * cb =
        Callback::Callback<DescriptorDeviceListListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void DescriptorClusterServerListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    chip::ClusterId data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(4);
        data[i] = emberAfGetInt32u(message, 0, 4);
        message += 4;
    }
    Callback::Callback<DescriptorServerListListAttributeCallback> * cb =
        Callback::Callback<DescriptorServerListListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void DescriptorClusterClientListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    chip::ClusterId data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(4);
        data[i] = emberAfGetInt32u(message, 0, 4);
        message += 4;
    }
    Callback::Callback<DescriptorClientListListAttributeCallback> * cb =
        Callback::Callback<DescriptorClientListListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void DescriptorClusterPartsListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    chip::EndpointId data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(2);
        data[i] = emberAfGetInt16u(message, 0, 2);
        message += 2;
    }
    Callback::Callback<DescriptorPartsListListAttributeCallback> * cb =
        Callback::Callback<DescriptorPartsListListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void FixedLabelClusterLabelListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback,
                                                   Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    _LabelStruct data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_STATUS_VOID(ReadByteSpan(message, 18, &data[i].label));
        messageLen = static_cast<uint16_t>(messageLen - 18);
        message += 18;
        CHECK_STATUS_VOID(ReadByteSpan(message, 18, &data[i].value));
        messageLen = static_cast<uint16_t>(messageLen - 18);
        message += 18;
    }
    Callback::Callback<FixedLabelLabelListListAttributeCallback> * cb =
        Callback::Callback<FixedLabelLabelListListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void GeneralDiagnosticsClusterNetworkInterfacesListAttributeFilter(TLV::TLVReader * tlvData,
                                                                   Callback::Cancelable * onSuccessCallback,
                                                                   Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    _NetworkInterfaceType data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_STATUS_VOID(ReadByteSpan(message, 34, &data[i].Name));
        messageLen = static_cast<uint16_t>(messageLen - 34);
        message += 34;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].FabricConnected = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].OffPremiseServicesReachableIPv4 = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].OffPremiseServicesReachableIPv6 = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_STATUS_VOID(ReadByteSpan(message, 10, &data[i].HardwareAddress));
        messageLen = static_cast<uint16_t>(messageLen - 10);
        message += 10;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].Type = emberAfGetInt8u(message, 0, 1);
        message += 1;
    }
    Callback::Callback<GeneralDiagnosticsNetworkInterfacesListAttributeCallback> * cb =
        Callback::Callback<GeneralDiagnosticsNetworkInterfacesListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void GroupKeyManagementClusterGroupsListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback,
                                                        Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    _GroupState data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(2);
        data[i].VendorId = emberAfGetInt16u(message, 0, 2);
        message += 2;
        CHECK_MESSAGE_LENGTH_VOID(2);
        data[i].VendorGroupId = emberAfGetInt16u(message, 0, 2);
        message += 2;
        CHECK_MESSAGE_LENGTH_VOID(2);
        data[i].GroupKeySetIndex = emberAfGetInt16u(message, 0, 2);
        message += 2;
    }
    Callback::Callback<GroupKeyManagementGroupsListAttributeCallback> * cb =
        Callback::Callback<GroupKeyManagementGroupsListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void GroupKeyManagementClusterGroupKeysListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback,
                                                           Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    _GroupKey data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(2);
        data[i].VendorId = emberAfGetInt16u(message, 0, 2);
        message += 2;
        CHECK_MESSAGE_LENGTH_VOID(2);
        data[i].GroupKeyIndex = emberAfGetInt16u(message, 0, 2);
        message += 2;
        CHECK_STATUS_VOID(ReadByteSpan(message, 18, &data[i].GroupKeyRoot));
        messageLen = static_cast<uint16_t>(messageLen - 18);
        message += 18;
        CHECK_MESSAGE_LENGTH_VOID(8);
        data[i].GroupKeyEpochStartTime = emberAfGetInt64u(message, 0, 8);
        message += 8;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].GroupKeySecurityPolicy = emberAfGetInt8u(message, 0, 1);
        message += 1;
    }
    Callback::Callback<GroupKeyManagementGroupKeysListAttributeCallback> * cb =
        Callback::Callback<GroupKeyManagementGroupKeysListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void MediaInputClusterMediaInputListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback,
                                                        Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    _MediaInputInfo data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].index = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].inputType = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_STATUS_VOID(ReadByteSpan(message, 34, &data[i].name));
        messageLen = static_cast<uint16_t>(messageLen - 34);
        message += 34;
        CHECK_STATUS_VOID(ReadByteSpan(message, 34, &data[i].description));
        messageLen = static_cast<uint16_t>(messageLen - 34);
        message += 34;
    }
    Callback::Callback<MediaInputMediaInputListListAttributeCallback> * cb =
        Callback::Callback<MediaInputMediaInputListListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void OperationalCredentialsClusterFabricsListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback,
                                                                 Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    _FabricDescriptor data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(8);
        data[i].FabricId = emberAfGetInt64u(message, 0, 8);
        message += 8;
        CHECK_MESSAGE_LENGTH_VOID(2);
        data[i].VendorId = emberAfGetInt16u(message, 0, 2);
        message += 2;
        CHECK_MESSAGE_LENGTH_VOID(8);
        data[i].NodeId = emberAfGetInt64u(message, 0, 8);
        message += 8;
        CHECK_STATUS_VOID(ReadByteSpan(message, 34, &data[i].Label));
        messageLen = static_cast<uint16_t>(messageLen - 34);
        message += 34;
    }
    Callback::Callback<OperationalCredentialsFabricsListListAttributeCallback> * cb =
        Callback::Callback<OperationalCredentialsFabricsListListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void TvChannelClusterTvChannelListListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback,
                                                      Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    _TvChannelInfo data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(2);
        data[i].majorNumber = emberAfGetInt16u(message, 0, 2);
        message += 2;
        CHECK_MESSAGE_LENGTH_VOID(2);
        data[i].minorNumber = emberAfGetInt16u(message, 0, 2);
        message += 2;
        CHECK_STATUS_VOID(ReadByteSpan(message, 34, &data[i].name));
        messageLen = static_cast<uint16_t>(messageLen - 34);
        message += 34;
        CHECK_STATUS_VOID(ReadByteSpan(message, 34, &data[i].callSign));
        messageLen = static_cast<uint16_t>(messageLen - 34);
        message += 34;
        CHECK_STATUS_VOID(ReadByteSpan(message, 34, &data[i].affiliateCallSign));
        messageLen = static_cast<uint16_t>(messageLen - 34);
        message += 34;
    }
    Callback::Callback<TvChannelTvChannelListListAttributeCallback> * cb =
        Callback::Callback<TvChannelTvChannelListListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void TargetNavigatorClusterTargetNavigatorListListAttributeFilter(TLV::TLVReader * tlvData,
                                                                  Callback::Cancelable * onSuccessCallback,
                                                                  Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    _NavigateTargetTargetInfo data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].identifier = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_STATUS_VOID(ReadByteSpan(message, 34, &data[i].name));
        messageLen = static_cast<uint16_t>(messageLen - 34);
        message += 34;
    }
    Callback::Callback<TargetNavigatorTargetNavigatorListListAttributeCallback> * cb =
        Callback::Callback<TargetNavigatorTargetNavigatorListListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void TestClusterClusterListInt8uListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback,
                                                    Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    uint8_t data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i] = emberAfGetInt8u(message, 0, 1);
        message += 1;
    }
    Callback::Callback<TestClusterListInt8uListAttributeCallback> * cb =
        Callback::Callback<TestClusterListInt8uListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void TestClusterClusterListOctetStringListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback,
                                                          Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    chip::ByteSpan data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_STATUS_VOID(ReadByteSpan(message, messageLen, &data[i]));
        uint16_t entryLength = static_cast<uint16_t>(data[i].size() + kByteSpanSizeLengthInBytes);
        messageLen           = static_cast<uint16_t>(messageLen - entryLength);
        message += entryLength;
    }
    Callback::Callback<TestClusterListOctetStringListAttributeCallback> * cb =
        Callback::Callback<TestClusterListOctetStringListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void TestClusterClusterListStructOctetStringListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback,
                                                                Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    _TestListStructOctet data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(8);
        data[i].fabricIndex = emberAfGetInt64u(message, 0, 8);
        message += 8;
        CHECK_STATUS_VOID(ReadByteSpan(message, 34, &data[i].operationalCert));
        messageLen = static_cast<uint16_t>(messageLen - 34);
        message += 34;
    }
    Callback::Callback<TestClusterListStructOctetStringListAttributeCallback> * cb =
        Callback::Callback<TestClusterListStructOctetStringListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void ThreadNetworkDiagnosticsClusterNeighborTableListListAttributeFilter(TLV::TLVReader * tlvData,
                                                                         Callback::Cancelable * onSuccessCallback,
                                                                         Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    _NeighborTable data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(8);
        data[i].ExtAddress = emberAfGetInt64u(message, 0, 8);
        message += 8;
        CHECK_MESSAGE_LENGTH_VOID(4);
        data[i].Age = emberAfGetInt32u(message, 0, 4);
        message += 4;
        CHECK_MESSAGE_LENGTH_VOID(2);
        data[i].Rloc16 = emberAfGetInt16u(message, 0, 2);
        message += 2;
        CHECK_MESSAGE_LENGTH_VOID(4);
        data[i].LinkFrameCounter = emberAfGetInt32u(message, 0, 4);
        message += 4;
        CHECK_MESSAGE_LENGTH_VOID(4);
        data[i].MleFrameCounter = emberAfGetInt32u(message, 0, 4);
        message += 4;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].LQI = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].AverageRssi = emberAfGetInt8s(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].LastRssi = emberAfGetInt8s(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].FrameErrorRate = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].MessageErrorRate = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].RxOnWhenIdle = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].FullThreadDevice = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].FullNetworkData = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].IsChild = emberAfGetInt8u(message, 0, 1);
        message += 1;
    }
    Callback::Callback<ThreadNetworkDiagnosticsNeighborTableListListAttributeCallback> * cb =
        Callback::Callback<ThreadNetworkDiagnosticsNeighborTableListListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void ThreadNetworkDiagnosticsClusterRouteTableListListAttributeFilter(TLV::TLVReader * tlvData,
                                                                      Callback::Cancelable * onSuccessCallback,
                                                                      Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    _RouteTable data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(8);
        data[i].ExtAddress = emberAfGetInt64u(message, 0, 8);
        message += 8;
        CHECK_MESSAGE_LENGTH_VOID(2);
        data[i].Rloc16 = emberAfGetInt16u(message, 0, 2);
        message += 2;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].RouterId = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].NextHop = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].PathCost = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].LQIIn = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].LQIOut = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].Age = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].Allocated = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].LinkEstablished = emberAfGetInt8u(message, 0, 1);
        message += 1;
    }
    Callback::Callback<ThreadNetworkDiagnosticsRouteTableListListAttributeCallback> * cb =
        Callback::Callback<ThreadNetworkDiagnosticsRouteTableListListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void ThreadNetworkDiagnosticsClusterSecurityPolicyListAttributeFilter(TLV::TLVReader * tlvData,
                                                                      Callback::Cancelable * onSuccessCallback,
                                                                      Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    _SecurityPolicy data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(2);
        data[i].RotationTime = emberAfGetInt16u(message, 0, 2);
        message += 2;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].Flags = emberAfGetInt8u(message, 0, 1);
        message += 1;
    }
    Callback::Callback<ThreadNetworkDiagnosticsSecurityPolicyListAttributeCallback> * cb =
        Callback::Callback<ThreadNetworkDiagnosticsSecurityPolicyListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void ThreadNetworkDiagnosticsClusterOperationalDatasetComponentsListAttributeFilter(TLV::TLVReader * tlvData,
                                                                                    Callback::Cancelable * onSuccessCallback,
                                                                                    Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    _OperationalDatasetComponents data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].ActiveTimestampPresent = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].PendingTimestampPresent = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].MasterKeyPresent = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].NetworkNamePresent = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].ExtendedPanIdPresent = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].MeshLocalPrefixPresent = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].DelayPresent = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].PanIdPresent = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].ChannelPresent = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].PskcPresent = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].SecurityPolicyPresent = emberAfGetInt8u(message, 0, 1);
        message += 1;
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i].ChannelMaskPresent = emberAfGetInt8u(message, 0, 1);
        message += 1;
    }
    Callback::Callback<ThreadNetworkDiagnosticsOperationalDatasetComponentsListAttributeCallback> * cb =
        Callback::Callback<ThreadNetworkDiagnosticsOperationalDatasetComponentsListAttributeCallback>::FromCancelable(
            onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

void ThreadNetworkDiagnosticsClusterActiveNetworkFaultsListListAttributeFilter(TLV::TLVReader * tlvData,
                                                                               Callback::Cancelable * onSuccessCallback,
                                                                               Callback::Cancelable * onFailureCallback)
{
    // TODO: Add actual support for array and lists.
    const uint8_t * message = nullptr;
    uint16_t messageLen     = 0;
    EmberAfStatus res       = PrepareListFromTLV(tlvData, message, messageLen);
    if (res != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, res);
        return;
    }

    CHECK_MESSAGE_LENGTH_VOID(2);
    uint16_t count = chip::Encoding::LittleEndian::Read16(message);
    uint8_t data[count];
    for (size_t i = 0; i < count; i++)
    {
        CHECK_MESSAGE_LENGTH_VOID(1);
        data[i] = emberAfGetInt8u(message, 0, 1);
        message += 1;
    }
    Callback::Callback<ThreadNetworkDiagnosticsActiveNetworkFaultsListListAttributeCallback> * cb =
        Callback::Callback<ThreadNetworkDiagnosticsActiveNetworkFaultsListListAttributeCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, count, data);
}

bool emberAfAccountLoginClusterGetSetupPINResponseCallback(chip::app::Command * commandObj, uint8_t * setupPIN)
{
    ChipLogProgress(Zcl, "GetSetupPINResponse:");
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  setupPIN: %.*s", setupPIN.size(), setupPIN.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("AccountLoginClusterGetSetupPINResponseCallback");

    Callback::Callback<AccountLoginClusterGetSetupPINResponseCallback> * cb =
        Callback::Callback<AccountLoginClusterGetSetupPINResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, setupPIN);
    return true;
}

bool emberAfApplicationLauncherClusterLaunchAppResponseCallback(chip::app::Command * commandObj, uint8_t status, uint8_t * data)
{
    ChipLogProgress(Zcl, "LaunchAppResponse:");
    LogStatus(status);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  data: %.*s", data.size(), data.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("ApplicationLauncherClusterLaunchAppResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<ApplicationLauncherClusterLaunchAppResponseCallback> * cb =
        Callback::Callback<ApplicationLauncherClusterLaunchAppResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, data);
    return true;
}

bool emberAfContentLauncherClusterLaunchContentResponseCallback(chip::app::Command * commandObj, uint8_t * data,
                                                                uint8_t contentLaunchStatus)
{
    ChipLogProgress(Zcl, "LaunchContentResponse:");
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  data: %.*s", data.size(), data.data());
    ChipLogProgress(Zcl, "  contentLaunchStatus: %" PRIu8 "", contentLaunchStatus);

    GET_CLUSTER_RESPONSE_CALLBACKS("ContentLauncherClusterLaunchContentResponseCallback");

    Callback::Callback<ContentLauncherClusterLaunchContentResponseCallback> * cb =
        Callback::Callback<ContentLauncherClusterLaunchContentResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, data, contentLaunchStatus);
    return true;
}

bool emberAfContentLauncherClusterLaunchURLResponseCallback(chip::app::Command * commandObj, uint8_t * data,
                                                            uint8_t contentLaunchStatus)
{
    ChipLogProgress(Zcl, "LaunchURLResponse:");
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  data: %.*s", data.size(), data.data());
    ChipLogProgress(Zcl, "  contentLaunchStatus: %" PRIu8 "", contentLaunchStatus);

    GET_CLUSTER_RESPONSE_CALLBACKS("ContentLauncherClusterLaunchURLResponseCallback");

    Callback::Callback<ContentLauncherClusterLaunchURLResponseCallback> * cb =
        Callback::Callback<ContentLauncherClusterLaunchURLResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, data, contentLaunchStatus);
    return true;
}

bool emberAfDoorLockClusterClearAllPinsResponseCallback(chip::app::Command * commandObj, uint8_t status)
{
    ChipLogProgress(Zcl, "ClearAllPinsResponse:");
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterClearAllPinsResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterClearAllPinsResponseCallback> * cb =
        Callback::Callback<DoorLockClusterClearAllPinsResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfDoorLockClusterClearAllRfidsResponseCallback(chip::app::Command * commandObj, uint8_t status)
{
    ChipLogProgress(Zcl, "ClearAllRfidsResponse:");
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterClearAllRfidsResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterClearAllRfidsResponseCallback> * cb =
        Callback::Callback<DoorLockClusterClearAllRfidsResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfDoorLockClusterClearHolidayScheduleResponseCallback(chip::app::Command * commandObj, uint8_t status)
{
    ChipLogProgress(Zcl, "ClearHolidayScheduleResponse:");
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterClearHolidayScheduleResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterClearHolidayScheduleResponseCallback> * cb =
        Callback::Callback<DoorLockClusterClearHolidayScheduleResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfDoorLockClusterClearPinResponseCallback(chip::app::Command * commandObj, uint8_t status)
{
    ChipLogProgress(Zcl, "ClearPinResponse:");
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterClearPinResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterClearPinResponseCallback> * cb =
        Callback::Callback<DoorLockClusterClearPinResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfDoorLockClusterClearRfidResponseCallback(chip::app::Command * commandObj, uint8_t status)
{
    ChipLogProgress(Zcl, "ClearRfidResponse:");
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterClearRfidResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterClearRfidResponseCallback> * cb =
        Callback::Callback<DoorLockClusterClearRfidResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfDoorLockClusterClearWeekdayScheduleResponseCallback(chip::app::Command * commandObj, uint8_t status)
{
    ChipLogProgress(Zcl, "ClearWeekdayScheduleResponse:");
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterClearWeekdayScheduleResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterClearWeekdayScheduleResponseCallback> * cb =
        Callback::Callback<DoorLockClusterClearWeekdayScheduleResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfDoorLockClusterClearYeardayScheduleResponseCallback(chip::app::Command * commandObj, uint8_t status)
{
    ChipLogProgress(Zcl, "ClearYeardayScheduleResponse:");
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterClearYeardayScheduleResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterClearYeardayScheduleResponseCallback> * cb =
        Callback::Callback<DoorLockClusterClearYeardayScheduleResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfDoorLockClusterGetHolidayScheduleResponseCallback(chip::app::Command * commandObj, uint8_t scheduleId, uint8_t status,
                                                              uint32_t localStartTime, uint32_t localEndTime,
                                                              uint8_t operatingModeDuringHoliday)
{
    ChipLogProgress(Zcl, "GetHolidayScheduleResponse:");
    ChipLogProgress(Zcl, "  scheduleId: %" PRIu8 "", scheduleId);
    LogStatus(status);
    ChipLogProgress(Zcl, "  localStartTime: %" PRIu32 "", localStartTime);
    ChipLogProgress(Zcl, "  localEndTime: %" PRIu32 "", localEndTime);
    ChipLogProgress(Zcl, "  operatingModeDuringHoliday: %" PRIu8 "", operatingModeDuringHoliday);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterGetHolidayScheduleResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterGetHolidayScheduleResponseCallback> * cb =
        Callback::Callback<DoorLockClusterGetHolidayScheduleResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, scheduleId, localStartTime, localEndTime, operatingModeDuringHoliday);
    return true;
}

bool emberAfDoorLockClusterGetLogRecordResponseCallback(chip::app::Command * commandObj, uint16_t logEntryId, uint32_t timestamp,
                                                        uint8_t eventType, uint8_t source, uint8_t eventIdOrAlarmCode,
                                                        uint16_t userId, uint8_t * pin)
{
    ChipLogProgress(Zcl, "GetLogRecordResponse:");
    ChipLogProgress(Zcl, "  logEntryId: %" PRIu16 "", logEntryId);
    ChipLogProgress(Zcl, "  timestamp: %" PRIu32 "", timestamp);
    ChipLogProgress(Zcl, "  eventType: %" PRIu8 "", eventType);
    ChipLogProgress(Zcl, "  source: %" PRIu8 "", source);
    ChipLogProgress(Zcl, "  eventIdOrAlarmCode: %" PRIu8 "", eventIdOrAlarmCode);
    ChipLogProgress(Zcl, "  userId: %" PRIu16 "", userId);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  pin: %.*s", pin.size(), pin.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterGetLogRecordResponseCallback");

    Callback::Callback<DoorLockClusterGetLogRecordResponseCallback> * cb =
        Callback::Callback<DoorLockClusterGetLogRecordResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, logEntryId, timestamp, eventType, source, eventIdOrAlarmCode, userId, pin);
    return true;
}

bool emberAfDoorLockClusterGetPinResponseCallback(chip::app::Command * commandObj, uint16_t userId, uint8_t userStatus,
                                                  uint8_t userType, uint8_t * pin)
{
    ChipLogProgress(Zcl, "GetPinResponse:");
    ChipLogProgress(Zcl, "  userId: %" PRIu16 "", userId);
    ChipLogProgress(Zcl, "  userStatus: %" PRIu8 "", userStatus);
    ChipLogProgress(Zcl, "  userType: %" PRIu8 "", userType);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  pin: %.*s", pin.size(), pin.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterGetPinResponseCallback");

    Callback::Callback<DoorLockClusterGetPinResponseCallback> * cb =
        Callback::Callback<DoorLockClusterGetPinResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, userId, userStatus, userType, pin);
    return true;
}

bool emberAfDoorLockClusterGetRfidResponseCallback(chip::app::Command * commandObj, uint16_t userId, uint8_t userStatus,
                                                   uint8_t userType, uint8_t * rfid)
{
    ChipLogProgress(Zcl, "GetRfidResponse:");
    ChipLogProgress(Zcl, "  userId: %" PRIu16 "", userId);
    ChipLogProgress(Zcl, "  userStatus: %" PRIu8 "", userStatus);
    ChipLogProgress(Zcl, "  userType: %" PRIu8 "", userType);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  rfid: %.*s", rfid.size(), rfid.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterGetRfidResponseCallback");

    Callback::Callback<DoorLockClusterGetRfidResponseCallback> * cb =
        Callback::Callback<DoorLockClusterGetRfidResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, userId, userStatus, userType, rfid);
    return true;
}

bool emberAfDoorLockClusterGetUserTypeResponseCallback(chip::app::Command * commandObj, uint16_t userId, uint8_t userType)
{
    ChipLogProgress(Zcl, "GetUserTypeResponse:");
    ChipLogProgress(Zcl, "  userId: %" PRIu16 "", userId);
    ChipLogProgress(Zcl, "  userType: %" PRIu8 "", userType);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterGetUserTypeResponseCallback");

    Callback::Callback<DoorLockClusterGetUserTypeResponseCallback> * cb =
        Callback::Callback<DoorLockClusterGetUserTypeResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, userId, userType);
    return true;
}

bool emberAfDoorLockClusterGetWeekdayScheduleResponseCallback(chip::app::Command * commandObj, uint8_t scheduleId, uint16_t userId,
                                                              uint8_t status, uint8_t daysMask, uint8_t startHour,
                                                              uint8_t startMinute, uint8_t endHour, uint8_t endMinute)
{
    ChipLogProgress(Zcl, "GetWeekdayScheduleResponse:");
    ChipLogProgress(Zcl, "  scheduleId: %" PRIu8 "", scheduleId);
    ChipLogProgress(Zcl, "  userId: %" PRIu16 "", userId);
    LogStatus(status);
    ChipLogProgress(Zcl, "  daysMask: %" PRIu8 "", daysMask);
    ChipLogProgress(Zcl, "  startHour: %" PRIu8 "", startHour);
    ChipLogProgress(Zcl, "  startMinute: %" PRIu8 "", startMinute);
    ChipLogProgress(Zcl, "  endHour: %" PRIu8 "", endHour);
    ChipLogProgress(Zcl, "  endMinute: %" PRIu8 "", endMinute);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterGetWeekdayScheduleResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterGetWeekdayScheduleResponseCallback> * cb =
        Callback::Callback<DoorLockClusterGetWeekdayScheduleResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, scheduleId, userId, daysMask, startHour, startMinute, endHour, endMinute);
    return true;
}

bool emberAfDoorLockClusterGetYeardayScheduleResponseCallback(chip::app::Command * commandObj, uint8_t scheduleId, uint16_t userId,
                                                              uint8_t status, uint32_t localStartTime, uint32_t localEndTime)
{
    ChipLogProgress(Zcl, "GetYeardayScheduleResponse:");
    ChipLogProgress(Zcl, "  scheduleId: %" PRIu8 "", scheduleId);
    ChipLogProgress(Zcl, "  userId: %" PRIu16 "", userId);
    LogStatus(status);
    ChipLogProgress(Zcl, "  localStartTime: %" PRIu32 "", localStartTime);
    ChipLogProgress(Zcl, "  localEndTime: %" PRIu32 "", localEndTime);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterGetYeardayScheduleResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterGetYeardayScheduleResponseCallback> * cb =
        Callback::Callback<DoorLockClusterGetYeardayScheduleResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, scheduleId, userId, localStartTime, localEndTime);
    return true;
}

bool emberAfDoorLockClusterLockDoorResponseCallback(chip::app::Command * commandObj, uint8_t status)
{
    ChipLogProgress(Zcl, "LockDoorResponse:");
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterLockDoorResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterLockDoorResponseCallback> * cb =
        Callback::Callback<DoorLockClusterLockDoorResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfDoorLockClusterSetHolidayScheduleResponseCallback(chip::app::Command * commandObj, uint8_t status)
{
    ChipLogProgress(Zcl, "SetHolidayScheduleResponse:");
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterSetHolidayScheduleResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterSetHolidayScheduleResponseCallback> * cb =
        Callback::Callback<DoorLockClusterSetHolidayScheduleResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfDoorLockClusterSetPinResponseCallback(chip::app::Command * commandObj, uint8_t status)
{
    ChipLogProgress(Zcl, "SetPinResponse:");
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterSetPinResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterSetPinResponseCallback> * cb =
        Callback::Callback<DoorLockClusterSetPinResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfDoorLockClusterSetRfidResponseCallback(chip::app::Command * commandObj, uint8_t status)
{
    ChipLogProgress(Zcl, "SetRfidResponse:");
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterSetRfidResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterSetRfidResponseCallback> * cb =
        Callback::Callback<DoorLockClusterSetRfidResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfDoorLockClusterSetUserTypeResponseCallback(chip::app::Command * commandObj, uint8_t status)
{
    ChipLogProgress(Zcl, "SetUserTypeResponse:");
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterSetUserTypeResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterSetUserTypeResponseCallback> * cb =
        Callback::Callback<DoorLockClusterSetUserTypeResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfDoorLockClusterSetWeekdayScheduleResponseCallback(chip::app::Command * commandObj, uint8_t status)
{
    ChipLogProgress(Zcl, "SetWeekdayScheduleResponse:");
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterSetWeekdayScheduleResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterSetWeekdayScheduleResponseCallback> * cb =
        Callback::Callback<DoorLockClusterSetWeekdayScheduleResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfDoorLockClusterSetYeardayScheduleResponseCallback(chip::app::Command * commandObj, uint8_t status)
{
    ChipLogProgress(Zcl, "SetYeardayScheduleResponse:");
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterSetYeardayScheduleResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterSetYeardayScheduleResponseCallback> * cb =
        Callback::Callback<DoorLockClusterSetYeardayScheduleResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfDoorLockClusterUnlockDoorResponseCallback(chip::app::Command * commandObj, uint8_t status)
{
    ChipLogProgress(Zcl, "UnlockDoorResponse:");
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterUnlockDoorResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterUnlockDoorResponseCallback> * cb =
        Callback::Callback<DoorLockClusterUnlockDoorResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfDoorLockClusterUnlockWithTimeoutResponseCallback(chip::app::Command * commandObj, uint8_t status)
{
    ChipLogProgress(Zcl, "UnlockWithTimeoutResponse:");
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("DoorLockClusterUnlockWithTimeoutResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<DoorLockClusterUnlockWithTimeoutResponseCallback> * cb =
        Callback::Callback<DoorLockClusterUnlockWithTimeoutResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfGeneralCommissioningClusterArmFailSafeResponseCallback(chip::app::Command * commandObj, uint8_t errorCode,
                                                                   uint8_t * debugText)
{
    ChipLogProgress(Zcl, "ArmFailSafeResponse:");
    ChipLogProgress(Zcl, "  errorCode: %" PRIu8 "", errorCode);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  debugText: %.*s", debugText.size(), debugText.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("GeneralCommissioningClusterArmFailSafeResponseCallback");

    Callback::Callback<GeneralCommissioningClusterArmFailSafeResponseCallback> * cb =
        Callback::Callback<GeneralCommissioningClusterArmFailSafeResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, errorCode, debugText);
    return true;
}

bool emberAfGeneralCommissioningClusterCommissioningCompleteResponseCallback(chip::app::Command * commandObj, uint8_t errorCode,
                                                                             uint8_t * debugText)
{
    ChipLogProgress(Zcl, "CommissioningCompleteResponse:");
    ChipLogProgress(Zcl, "  errorCode: %" PRIu8 "", errorCode);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  debugText: %.*s", debugText.size(), debugText.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("GeneralCommissioningClusterCommissioningCompleteResponseCallback");

    Callback::Callback<GeneralCommissioningClusterCommissioningCompleteResponseCallback> * cb =
        Callback::Callback<GeneralCommissioningClusterCommissioningCompleteResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, errorCode, debugText);
    return true;
}

bool emberAfGeneralCommissioningClusterSetRegulatoryConfigResponseCallback(chip::app::Command * commandObj, uint8_t errorCode,
                                                                           uint8_t * debugText)
{
    ChipLogProgress(Zcl, "SetRegulatoryConfigResponse:");
    ChipLogProgress(Zcl, "  errorCode: %" PRIu8 "", errorCode);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  debugText: %.*s", debugText.size(), debugText.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("GeneralCommissioningClusterSetRegulatoryConfigResponseCallback");

    Callback::Callback<GeneralCommissioningClusterSetRegulatoryConfigResponseCallback> * cb =
        Callback::Callback<GeneralCommissioningClusterSetRegulatoryConfigResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, errorCode, debugText);
    return true;
}

bool emberAfGroupsClusterAddGroupResponseCallback(chip::app::Command * commandObj, uint8_t status, uint16_t groupId)
{
    ChipLogProgress(Zcl, "AddGroupResponse:");
    LogStatus(status);
    ChipLogProgress(Zcl, "  groupId: %" PRIu16 "", groupId);

    GET_CLUSTER_RESPONSE_CALLBACKS("GroupsClusterAddGroupResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<GroupsClusterAddGroupResponseCallback> * cb =
        Callback::Callback<GroupsClusterAddGroupResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, groupId);
    return true;
}

bool emberAfGroupsClusterGetGroupMembershipResponseCallback(chip::app::Command * commandObj, uint8_t capacity, uint8_t groupCount,
                                                            /* TYPE WARNING: array array defaults to */ uint8_t * groupList)
{
    ChipLogProgress(Zcl, "GetGroupMembershipResponse:");
    ChipLogProgress(Zcl, "  capacity: %" PRIu8 "", capacity);
    ChipLogProgress(Zcl, "  groupCount: %" PRIu8 "", groupCount);
    ChipLogProgress(Zcl, "  groupList: %p", groupList);

    GET_CLUSTER_RESPONSE_CALLBACKS("GroupsClusterGetGroupMembershipResponseCallback");

    Callback::Callback<GroupsClusterGetGroupMembershipResponseCallback> * cb =
        Callback::Callback<GroupsClusterGetGroupMembershipResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, capacity, groupCount, groupList);
    return true;
}

bool emberAfGroupsClusterRemoveGroupResponseCallback(chip::app::Command * commandObj, uint8_t status, uint16_t groupId)
{
    ChipLogProgress(Zcl, "RemoveGroupResponse:");
    LogStatus(status);
    ChipLogProgress(Zcl, "  groupId: %" PRIu16 "", groupId);

    GET_CLUSTER_RESPONSE_CALLBACKS("GroupsClusterRemoveGroupResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<GroupsClusterRemoveGroupResponseCallback> * cb =
        Callback::Callback<GroupsClusterRemoveGroupResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, groupId);
    return true;
}

bool emberAfGroupsClusterViewGroupResponseCallback(chip::app::Command * commandObj, uint8_t status, uint16_t groupId,
                                                   uint8_t * groupName)
{
    ChipLogProgress(Zcl, "ViewGroupResponse:");
    LogStatus(status);
    ChipLogProgress(Zcl, "  groupId: %" PRIu16 "", groupId);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  groupName: %.*s", groupName.size(), groupName.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("GroupsClusterViewGroupResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<GroupsClusterViewGroupResponseCallback> * cb =
        Callback::Callback<GroupsClusterViewGroupResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, groupId, groupName);
    return true;
}

bool emberAfIdentifyClusterIdentifyQueryResponseCallback(chip::app::Command * commandObj, uint16_t timeout)
{
    ChipLogProgress(Zcl, "IdentifyQueryResponse:");
    ChipLogProgress(Zcl, "  timeout: %" PRIu16 "", timeout);

    GET_CLUSTER_RESPONSE_CALLBACKS("IdentifyClusterIdentifyQueryResponseCallback");

    Callback::Callback<IdentifyClusterIdentifyQueryResponseCallback> * cb =
        Callback::Callback<IdentifyClusterIdentifyQueryResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, timeout);
    return true;
}

bool emberAfKeypadInputClusterSendKeyResponseCallback(chip::app::Command * commandObj, uint8_t status)
{
    ChipLogProgress(Zcl, "SendKeyResponse:");
    LogStatus(status);

    GET_CLUSTER_RESPONSE_CALLBACKS("KeypadInputClusterSendKeyResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<KeypadInputClusterSendKeyResponseCallback> * cb =
        Callback::Callback<KeypadInputClusterSendKeyResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext);
    return true;
}

bool emberAfMediaPlaybackClusterMediaFastForwardResponseCallback(chip::app::Command * commandObj, uint8_t mediaPlaybackStatus)
{
    ChipLogProgress(Zcl, "MediaFastForwardResponse:");
    ChipLogProgress(Zcl, "  mediaPlaybackStatus: %" PRIu8 "", mediaPlaybackStatus);

    GET_CLUSTER_RESPONSE_CALLBACKS("MediaPlaybackClusterMediaFastForwardResponseCallback");

    Callback::Callback<MediaPlaybackClusterMediaFastForwardResponseCallback> * cb =
        Callback::Callback<MediaPlaybackClusterMediaFastForwardResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, mediaPlaybackStatus);
    return true;
}

bool emberAfMediaPlaybackClusterMediaNextResponseCallback(chip::app::Command * commandObj, uint8_t mediaPlaybackStatus)
{
    ChipLogProgress(Zcl, "MediaNextResponse:");
    ChipLogProgress(Zcl, "  mediaPlaybackStatus: %" PRIu8 "", mediaPlaybackStatus);

    GET_CLUSTER_RESPONSE_CALLBACKS("MediaPlaybackClusterMediaNextResponseCallback");

    Callback::Callback<MediaPlaybackClusterMediaNextResponseCallback> * cb =
        Callback::Callback<MediaPlaybackClusterMediaNextResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, mediaPlaybackStatus);
    return true;
}

bool emberAfMediaPlaybackClusterMediaPauseResponseCallback(chip::app::Command * commandObj, uint8_t mediaPlaybackStatus)
{
    ChipLogProgress(Zcl, "MediaPauseResponse:");
    ChipLogProgress(Zcl, "  mediaPlaybackStatus: %" PRIu8 "", mediaPlaybackStatus);

    GET_CLUSTER_RESPONSE_CALLBACKS("MediaPlaybackClusterMediaPauseResponseCallback");

    Callback::Callback<MediaPlaybackClusterMediaPauseResponseCallback> * cb =
        Callback::Callback<MediaPlaybackClusterMediaPauseResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, mediaPlaybackStatus);
    return true;
}

bool emberAfMediaPlaybackClusterMediaPlayResponseCallback(chip::app::Command * commandObj, uint8_t mediaPlaybackStatus)
{
    ChipLogProgress(Zcl, "MediaPlayResponse:");
    ChipLogProgress(Zcl, "  mediaPlaybackStatus: %" PRIu8 "", mediaPlaybackStatus);

    GET_CLUSTER_RESPONSE_CALLBACKS("MediaPlaybackClusterMediaPlayResponseCallback");

    Callback::Callback<MediaPlaybackClusterMediaPlayResponseCallback> * cb =
        Callback::Callback<MediaPlaybackClusterMediaPlayResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, mediaPlaybackStatus);
    return true;
}

bool emberAfMediaPlaybackClusterMediaPreviousResponseCallback(chip::app::Command * commandObj, uint8_t mediaPlaybackStatus)
{
    ChipLogProgress(Zcl, "MediaPreviousResponse:");
    ChipLogProgress(Zcl, "  mediaPlaybackStatus: %" PRIu8 "", mediaPlaybackStatus);

    GET_CLUSTER_RESPONSE_CALLBACKS("MediaPlaybackClusterMediaPreviousResponseCallback");

    Callback::Callback<MediaPlaybackClusterMediaPreviousResponseCallback> * cb =
        Callback::Callback<MediaPlaybackClusterMediaPreviousResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, mediaPlaybackStatus);
    return true;
}

bool emberAfMediaPlaybackClusterMediaRewindResponseCallback(chip::app::Command * commandObj, uint8_t mediaPlaybackStatus)
{
    ChipLogProgress(Zcl, "MediaRewindResponse:");
    ChipLogProgress(Zcl, "  mediaPlaybackStatus: %" PRIu8 "", mediaPlaybackStatus);

    GET_CLUSTER_RESPONSE_CALLBACKS("MediaPlaybackClusterMediaRewindResponseCallback");

    Callback::Callback<MediaPlaybackClusterMediaRewindResponseCallback> * cb =
        Callback::Callback<MediaPlaybackClusterMediaRewindResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, mediaPlaybackStatus);
    return true;
}

bool emberAfMediaPlaybackClusterMediaSeekResponseCallback(chip::app::Command * commandObj, uint8_t mediaPlaybackStatus)
{
    ChipLogProgress(Zcl, "MediaSeekResponse:");
    ChipLogProgress(Zcl, "  mediaPlaybackStatus: %" PRIu8 "", mediaPlaybackStatus);

    GET_CLUSTER_RESPONSE_CALLBACKS("MediaPlaybackClusterMediaSeekResponseCallback");

    Callback::Callback<MediaPlaybackClusterMediaSeekResponseCallback> * cb =
        Callback::Callback<MediaPlaybackClusterMediaSeekResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, mediaPlaybackStatus);
    return true;
}

bool emberAfMediaPlaybackClusterMediaSkipBackwardResponseCallback(chip::app::Command * commandObj, uint8_t mediaPlaybackStatus)
{
    ChipLogProgress(Zcl, "MediaSkipBackwardResponse:");
    ChipLogProgress(Zcl, "  mediaPlaybackStatus: %" PRIu8 "", mediaPlaybackStatus);

    GET_CLUSTER_RESPONSE_CALLBACKS("MediaPlaybackClusterMediaSkipBackwardResponseCallback");

    Callback::Callback<MediaPlaybackClusterMediaSkipBackwardResponseCallback> * cb =
        Callback::Callback<MediaPlaybackClusterMediaSkipBackwardResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, mediaPlaybackStatus);
    return true;
}

bool emberAfMediaPlaybackClusterMediaSkipForwardResponseCallback(chip::app::Command * commandObj, uint8_t mediaPlaybackStatus)
{
    ChipLogProgress(Zcl, "MediaSkipForwardResponse:");
    ChipLogProgress(Zcl, "  mediaPlaybackStatus: %" PRIu8 "", mediaPlaybackStatus);

    GET_CLUSTER_RESPONSE_CALLBACKS("MediaPlaybackClusterMediaSkipForwardResponseCallback");

    Callback::Callback<MediaPlaybackClusterMediaSkipForwardResponseCallback> * cb =
        Callback::Callback<MediaPlaybackClusterMediaSkipForwardResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, mediaPlaybackStatus);
    return true;
}

bool emberAfMediaPlaybackClusterMediaStartOverResponseCallback(chip::app::Command * commandObj, uint8_t mediaPlaybackStatus)
{
    ChipLogProgress(Zcl, "MediaStartOverResponse:");
    ChipLogProgress(Zcl, "  mediaPlaybackStatus: %" PRIu8 "", mediaPlaybackStatus);

    GET_CLUSTER_RESPONSE_CALLBACKS("MediaPlaybackClusterMediaStartOverResponseCallback");

    Callback::Callback<MediaPlaybackClusterMediaStartOverResponseCallback> * cb =
        Callback::Callback<MediaPlaybackClusterMediaStartOverResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, mediaPlaybackStatus);
    return true;
}

bool emberAfMediaPlaybackClusterMediaStopResponseCallback(chip::app::Command * commandObj, uint8_t mediaPlaybackStatus)
{
    ChipLogProgress(Zcl, "MediaStopResponse:");
    ChipLogProgress(Zcl, "  mediaPlaybackStatus: %" PRIu8 "", mediaPlaybackStatus);

    GET_CLUSTER_RESPONSE_CALLBACKS("MediaPlaybackClusterMediaStopResponseCallback");

    Callback::Callback<MediaPlaybackClusterMediaStopResponseCallback> * cb =
        Callback::Callback<MediaPlaybackClusterMediaStopResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, mediaPlaybackStatus);
    return true;
}

bool emberAfNetworkCommissioningClusterAddThreadNetworkResponseCallback(chip::app::Command * commandObj, uint8_t errorCode,
                                                                        uint8_t * debugText)
{
    ChipLogProgress(Zcl, "AddThreadNetworkResponse:");
    ChipLogProgress(Zcl, "  errorCode: %" PRIu8 "", errorCode);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  debugText: %.*s", debugText.size(), debugText.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("NetworkCommissioningClusterAddThreadNetworkResponseCallback");

    Callback::Callback<NetworkCommissioningClusterAddThreadNetworkResponseCallback> * cb =
        Callback::Callback<NetworkCommissioningClusterAddThreadNetworkResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, errorCode, debugText);
    return true;
}

bool emberAfNetworkCommissioningClusterAddWiFiNetworkResponseCallback(chip::app::Command * commandObj, uint8_t errorCode,
                                                                      uint8_t * debugText)
{
    ChipLogProgress(Zcl, "AddWiFiNetworkResponse:");
    ChipLogProgress(Zcl, "  errorCode: %" PRIu8 "", errorCode);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  debugText: %.*s", debugText.size(), debugText.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("NetworkCommissioningClusterAddWiFiNetworkResponseCallback");

    Callback::Callback<NetworkCommissioningClusterAddWiFiNetworkResponseCallback> * cb =
        Callback::Callback<NetworkCommissioningClusterAddWiFiNetworkResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, errorCode, debugText);
    return true;
}

bool emberAfNetworkCommissioningClusterDisableNetworkResponseCallback(chip::app::Command * commandObj, uint8_t errorCode,
                                                                      uint8_t * debugText)
{
    ChipLogProgress(Zcl, "DisableNetworkResponse:");
    ChipLogProgress(Zcl, "  errorCode: %" PRIu8 "", errorCode);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  debugText: %.*s", debugText.size(), debugText.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("NetworkCommissioningClusterDisableNetworkResponseCallback");

    Callback::Callback<NetworkCommissioningClusterDisableNetworkResponseCallback> * cb =
        Callback::Callback<NetworkCommissioningClusterDisableNetworkResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, errorCode, debugText);
    return true;
}

bool emberAfNetworkCommissioningClusterEnableNetworkResponseCallback(chip::app::Command * commandObj, uint8_t errorCode,
                                                                     uint8_t * debugText)
{
    ChipLogProgress(Zcl, "EnableNetworkResponse:");
    ChipLogProgress(Zcl, "  errorCode: %" PRIu8 "", errorCode);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  debugText: %.*s", debugText.size(), debugText.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("NetworkCommissioningClusterEnableNetworkResponseCallback");

    Callback::Callback<NetworkCommissioningClusterEnableNetworkResponseCallback> * cb =
        Callback::Callback<NetworkCommissioningClusterEnableNetworkResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, errorCode, debugText);
    return true;
}

bool emberAfNetworkCommissioningClusterRemoveNetworkResponseCallback(chip::app::Command * commandObj, uint8_t errorCode,
                                                                     uint8_t * debugText)
{
    ChipLogProgress(Zcl, "RemoveNetworkResponse:");
    ChipLogProgress(Zcl, "  errorCode: %" PRIu8 "", errorCode);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  debugText: %.*s", debugText.size(), debugText.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("NetworkCommissioningClusterRemoveNetworkResponseCallback");

    Callback::Callback<NetworkCommissioningClusterRemoveNetworkResponseCallback> * cb =
        Callback::Callback<NetworkCommissioningClusterRemoveNetworkResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, errorCode, debugText);
    return true;
}

bool emberAfNetworkCommissioningClusterScanNetworksResponseCallback(
    chip::app::Command * commandObj, uint8_t errorCode, uint8_t * debugText,
    /* TYPE WARNING: array array defaults to */ uint8_t * wifiScanResults,
    /* TYPE WARNING: array array defaults to */ uint8_t * threadScanResults)
{
    ChipLogProgress(Zcl, "ScanNetworksResponse:");
    ChipLogProgress(Zcl, "  errorCode: %" PRIu8 "", errorCode);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  debugText: %.*s", debugText.size(), debugText.data());
    ChipLogProgress(Zcl, "  wifiScanResults: %p", wifiScanResults);
    ChipLogProgress(Zcl, "  threadScanResults: %p", threadScanResults);

    GET_CLUSTER_RESPONSE_CALLBACKS("NetworkCommissioningClusterScanNetworksResponseCallback");

    Callback::Callback<NetworkCommissioningClusterScanNetworksResponseCallback> * cb =
        Callback::Callback<NetworkCommissioningClusterScanNetworksResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, errorCode, debugText, wifiScanResults, threadScanResults);
    return true;
}

bool emberAfNetworkCommissioningClusterUpdateThreadNetworkResponseCallback(chip::app::Command * commandObj, uint8_t errorCode,
                                                                           uint8_t * debugText)
{
    ChipLogProgress(Zcl, "UpdateThreadNetworkResponse:");
    ChipLogProgress(Zcl, "  errorCode: %" PRIu8 "", errorCode);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  debugText: %.*s", debugText.size(), debugText.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("NetworkCommissioningClusterUpdateThreadNetworkResponseCallback");

    Callback::Callback<NetworkCommissioningClusterUpdateThreadNetworkResponseCallback> * cb =
        Callback::Callback<NetworkCommissioningClusterUpdateThreadNetworkResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, errorCode, debugText);
    return true;
}

bool emberAfNetworkCommissioningClusterUpdateWiFiNetworkResponseCallback(chip::app::Command * commandObj, uint8_t errorCode,
                                                                         uint8_t * debugText)
{
    ChipLogProgress(Zcl, "UpdateWiFiNetworkResponse:");
    ChipLogProgress(Zcl, "  errorCode: %" PRIu8 "", errorCode);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  debugText: %.*s", debugText.size(), debugText.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("NetworkCommissioningClusterUpdateWiFiNetworkResponseCallback");

    Callback::Callback<NetworkCommissioningClusterUpdateWiFiNetworkResponseCallback> * cb =
        Callback::Callback<NetworkCommissioningClusterUpdateWiFiNetworkResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, errorCode, debugText);
    return true;
}

bool emberAfOtaSoftwareUpdateProviderClusterApplyUpdateRequestResponseCallback(chip::app::Command * commandObj, uint8_t action,
                                                                               uint32_t delayedActionTime)
{
    ChipLogProgress(Zcl, "ApplyUpdateRequestResponse:");
    ChipLogProgress(Zcl, "  action: %" PRIu8 "", action);
    ChipLogProgress(Zcl, "  delayedActionTime: %" PRIu32 "", delayedActionTime);

    GET_CLUSTER_RESPONSE_CALLBACKS("OtaSoftwareUpdateProviderClusterApplyUpdateRequestResponseCallback");

    Callback::Callback<OtaSoftwareUpdateProviderClusterApplyUpdateRequestResponseCallback> * cb =
        Callback::Callback<OtaSoftwareUpdateProviderClusterApplyUpdateRequestResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, action, delayedActionTime);
    return true;
}

bool emberAfOtaSoftwareUpdateProviderClusterQueryImageResponseCallback(chip::app::Command * commandObj, uint8_t status,
                                                                       uint32_t delayedActionTime, uint8_t * imageURI,
                                                                       uint32_t softwareVersion, chip::ByteSpan updateToken,
                                                                       uint8_t userConsentNeeded,
                                                                       chip::ByteSpan metadataForRequestor)
{
    ChipLogProgress(Zcl, "QueryImageResponse:");
    LogStatus(status);
    ChipLogProgress(Zcl, "  delayedActionTime: %" PRIu32 "", delayedActionTime);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  imageURI: %.*s", imageURI.size(), imageURI.data());
    ChipLogProgress(Zcl, "  softwareVersion: %" PRIu32 "", softwareVersion);
    ChipLogProgress(Zcl, "  updateToken: %zu", updateToken.size());
    ChipLogProgress(Zcl, "  userConsentNeeded: %" PRIu8 "", userConsentNeeded);
    ChipLogProgress(Zcl, "  metadataForRequestor: %zu", metadataForRequestor.size());

    GET_CLUSTER_RESPONSE_CALLBACKS("OtaSoftwareUpdateProviderClusterQueryImageResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<OtaSoftwareUpdateProviderClusterQueryImageResponseCallback> * cb =
        Callback::Callback<OtaSoftwareUpdateProviderClusterQueryImageResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, delayedActionTime, imageURI, softwareVersion, updateToken, userConsentNeeded, metadataForRequestor);
    return true;
}

bool emberAfOperationalCredentialsClusterOpCSRResponseCallback(chip::app::Command * commandObj, chip::ByteSpan CSR,
                                                               chip::ByteSpan CSRNonce, chip::ByteSpan VendorReserved1,
                                                               chip::ByteSpan VendorReserved2, chip::ByteSpan VendorReserved3,
                                                               chip::ByteSpan Signature)
{
    ChipLogProgress(Zcl, "OpCSRResponse:");
    ChipLogProgress(Zcl, "  CSR: %zu", CSR.size());
    ChipLogProgress(Zcl, "  CSRNonce: %zu", CSRNonce.size());
    ChipLogProgress(Zcl, "  VendorReserved1: %zu", VendorReserved1.size());
    ChipLogProgress(Zcl, "  VendorReserved2: %zu", VendorReserved2.size());
    ChipLogProgress(Zcl, "  VendorReserved3: %zu", VendorReserved3.size());
    ChipLogProgress(Zcl, "  Signature: %zu", Signature.size());

    GET_CLUSTER_RESPONSE_CALLBACKS("OperationalCredentialsClusterOpCSRResponseCallback");

    Callback::Callback<OperationalCredentialsClusterOpCSRResponseCallback> * cb =
        Callback::Callback<OperationalCredentialsClusterOpCSRResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, CSR, CSRNonce, VendorReserved1, VendorReserved2, VendorReserved3, Signature);
    return true;
}

bool emberAfOperationalCredentialsClusterOpCertResponseCallback(chip::app::Command * commandObj, uint8_t StatusCode,
                                                                uint64_t FabricIndex, uint8_t * DebugText)
{
    ChipLogProgress(Zcl, "OpCertResponse:");
    ChipLogProgress(Zcl, "  StatusCode: %" PRIu8 "", StatusCode);
    ChipLogProgress(Zcl, "  FabricIndex: %" PRIu64 "", FabricIndex);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  DebugText: %.*s", DebugText.size(), DebugText.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("OperationalCredentialsClusterOpCertResponseCallback");

    Callback::Callback<OperationalCredentialsClusterOpCertResponseCallback> * cb =
        Callback::Callback<OperationalCredentialsClusterOpCertResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, StatusCode, FabricIndex, DebugText);
    return true;
}

bool emberAfOperationalCredentialsClusterSetFabricResponseCallback(chip::app::Command * commandObj, chip::FabricId FabricId)
{
    ChipLogProgress(Zcl, "SetFabricResponse:");
    ChipLogProgress(Zcl, "  FabricId: %" PRIu64 "", FabricId);

    GET_CLUSTER_RESPONSE_CALLBACKS("OperationalCredentialsClusterSetFabricResponseCallback");

    Callback::Callback<OperationalCredentialsClusterSetFabricResponseCallback> * cb =
        Callback::Callback<OperationalCredentialsClusterSetFabricResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, FabricId);
    return true;
}

bool emberAfScenesClusterAddSceneResponseCallback(chip::app::Command * commandObj, uint8_t status, uint16_t groupId,
                                                  uint8_t sceneId)
{
    ChipLogProgress(Zcl, "AddSceneResponse:");
    LogStatus(status);
    ChipLogProgress(Zcl, "  groupId: %" PRIu16 "", groupId);
    ChipLogProgress(Zcl, "  sceneId: %" PRIu8 "", sceneId);

    GET_CLUSTER_RESPONSE_CALLBACKS("ScenesClusterAddSceneResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<ScenesClusterAddSceneResponseCallback> * cb =
        Callback::Callback<ScenesClusterAddSceneResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, groupId, sceneId);
    return true;
}

bool emberAfScenesClusterGetSceneMembershipResponseCallback(chip::app::Command * commandObj, uint8_t status, uint8_t capacity,
                                                            uint16_t groupId, uint8_t sceneCount,
                                                            /* TYPE WARNING: array array defaults to */ uint8_t * sceneList)
{
    ChipLogProgress(Zcl, "GetSceneMembershipResponse:");
    LogStatus(status);
    ChipLogProgress(Zcl, "  capacity: %" PRIu8 "", capacity);
    ChipLogProgress(Zcl, "  groupId: %" PRIu16 "", groupId);
    ChipLogProgress(Zcl, "  sceneCount: %" PRIu8 "", sceneCount);
    ChipLogProgress(Zcl, "  sceneList: %p", sceneList);

    GET_CLUSTER_RESPONSE_CALLBACKS("ScenesClusterGetSceneMembershipResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<ScenesClusterGetSceneMembershipResponseCallback> * cb =
        Callback::Callback<ScenesClusterGetSceneMembershipResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, capacity, groupId, sceneCount, sceneList);
    return true;
}

bool emberAfScenesClusterRemoveAllScenesResponseCallback(chip::app::Command * commandObj, uint8_t status, uint16_t groupId)
{
    ChipLogProgress(Zcl, "RemoveAllScenesResponse:");
    LogStatus(status);
    ChipLogProgress(Zcl, "  groupId: %" PRIu16 "", groupId);

    GET_CLUSTER_RESPONSE_CALLBACKS("ScenesClusterRemoveAllScenesResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<ScenesClusterRemoveAllScenesResponseCallback> * cb =
        Callback::Callback<ScenesClusterRemoveAllScenesResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, groupId);
    return true;
}

bool emberAfScenesClusterRemoveSceneResponseCallback(chip::app::Command * commandObj, uint8_t status, uint16_t groupId,
                                                     uint8_t sceneId)
{
    ChipLogProgress(Zcl, "RemoveSceneResponse:");
    LogStatus(status);
    ChipLogProgress(Zcl, "  groupId: %" PRIu16 "", groupId);
    ChipLogProgress(Zcl, "  sceneId: %" PRIu8 "", sceneId);

    GET_CLUSTER_RESPONSE_CALLBACKS("ScenesClusterRemoveSceneResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<ScenesClusterRemoveSceneResponseCallback> * cb =
        Callback::Callback<ScenesClusterRemoveSceneResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, groupId, sceneId);
    return true;
}

bool emberAfScenesClusterStoreSceneResponseCallback(chip::app::Command * commandObj, uint8_t status, uint16_t groupId,
                                                    uint8_t sceneId)
{
    ChipLogProgress(Zcl, "StoreSceneResponse:");
    LogStatus(status);
    ChipLogProgress(Zcl, "  groupId: %" PRIu16 "", groupId);
    ChipLogProgress(Zcl, "  sceneId: %" PRIu8 "", sceneId);

    GET_CLUSTER_RESPONSE_CALLBACKS("ScenesClusterStoreSceneResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<ScenesClusterStoreSceneResponseCallback> * cb =
        Callback::Callback<ScenesClusterStoreSceneResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, groupId, sceneId);
    return true;
}

bool emberAfScenesClusterViewSceneResponseCallback(chip::app::Command * commandObj, uint8_t status, uint16_t groupId,
                                                   uint8_t sceneId, uint16_t transitionTime, uint8_t * sceneName,
                                                   /* TYPE WARNING: array array defaults to */ uint8_t * extensionFieldSets)
{
    ChipLogProgress(Zcl, "ViewSceneResponse:");
    LogStatus(status);
    ChipLogProgress(Zcl, "  groupId: %" PRIu16 "", groupId);
    ChipLogProgress(Zcl, "  sceneId: %" PRIu8 "", sceneId);
    ChipLogProgress(Zcl, "  transitionTime: %" PRIu16 "", transitionTime);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  sceneName: %.*s", sceneName.size(), sceneName.data());
    ChipLogProgress(Zcl, "  extensionFieldSets: %p", extensionFieldSets);

    GET_CLUSTER_RESPONSE_CALLBACKS("ScenesClusterViewSceneResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<ScenesClusterViewSceneResponseCallback> * cb =
        Callback::Callback<ScenesClusterViewSceneResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, groupId, sceneId, transitionTime, sceneName, extensionFieldSets);
    return true;
}

bool emberAfTvChannelClusterChangeChannelResponseCallback(chip::app::Command * commandObj,
                                                          /* TYPE WARNING: array array defaults to */ uint8_t * ChannelMatch,
                                                          uint8_t ErrorType)
{
    ChipLogProgress(Zcl, "ChangeChannelResponse:");
    ChipLogProgress(Zcl, "  ChannelMatch: %p", ChannelMatch);
    ChipLogProgress(Zcl, "  ErrorType: %" PRIu8 "", ErrorType);

    GET_CLUSTER_RESPONSE_CALLBACKS("TvChannelClusterChangeChannelResponseCallback");

    Callback::Callback<TvChannelClusterChangeChannelResponseCallback> * cb =
        Callback::Callback<TvChannelClusterChangeChannelResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, ChannelMatch, ErrorType);
    return true;
}

bool emberAfTargetNavigatorClusterNavigateTargetResponseCallback(chip::app::Command * commandObj, uint8_t status, uint8_t * data)
{
    ChipLogProgress(Zcl, "NavigateTargetResponse:");
    LogStatus(status);
    // Currently the generated code emits `uint8_t *` for CHAR_STRING, it needs to emits chip::ByteSpan
    // ChipLogProgress(Zcl, "  data: %.*s", data.size(), data.data());

    GET_CLUSTER_RESPONSE_CALLBACKS("TargetNavigatorClusterNavigateTargetResponseCallback");

    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        Callback::Callback<DefaultFailureCallback> * cb =
            Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
        cb->mCall(cb->mContext, status);
        return true;
    }

    Callback::Callback<TargetNavigatorClusterNavigateTargetResponseCallback> * cb =
        Callback::Callback<TargetNavigatorClusterNavigateTargetResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, data);
    return true;
}

bool emberAfTestClusterClusterTestSpecificResponseCallback(chip::app::Command * commandObj, uint8_t returnValue)
{
    ChipLogProgress(Zcl, "TestSpecificResponse:");
    ChipLogProgress(Zcl, "  returnValue: %" PRIu8 "", returnValue);

    GET_CLUSTER_RESPONSE_CALLBACKS("TestClusterClusterTestSpecificResponseCallback");

    Callback::Callback<TestClusterClusterTestSpecificResponseCallback> * cb =
        Callback::Callback<TestClusterClusterTestSpecificResponseCallback>::FromCancelable(onSuccessCallback);
    cb->mCall(cb->mContext, returnValue);
    return true;
}

bool emberAfReportAttributesCallback(ClusterId clusterId, uint8_t * message, uint16_t messageLen)
{
    ChipLogProgress(Zcl, "emberAfReportAttributeCallback:");
    ChipLogProgress(Zcl, "  ClusterId: 0x%08x", clusterId);

    NodeId sourceId = emberAfCurrentCommand()->SourceNodeId();
    ChipLogProgress(Zcl, "  Source NodeId: %" PRIu64, sourceId);

    EndpointId endpointId = emberAfCurrentCommand()->apsFrame->sourceEndpoint;
    ChipLogProgress(Zcl, "  Source EndpointId: 0x%08x", endpointId);

    // TODO onFailureCallback is just here because of the CHECK_MESSAGE_LENGTH macro. It needs to be removed.
    Callback::Cancelable * onFailureCallback = nullptr;

    while (messageLen)
    {
        CHECK_MESSAGE_LENGTH(2);
        AttributeId attributeId = chip::Encoding::LittleEndian::Read32(message); // attribId
        ChipLogProgress(Zcl, "  attributeId: 0x%08x", attributeId);

        GET_REPORT_CALLBACK("emberAfReportAttributesCallback");

        CHECK_MESSAGE_LENGTH(1);
        uint8_t attributeType = chip::Encoding::Read8(message);
        ChipLogProgress(Zcl, "  attributeType: 0x%02x", attributeType);

        switch (attributeType)
        {
        case 0x00: // nodata / No data
        case 0x0A: // data24 / 24-bit data
        case 0x0C: // data40 / 40-bit data
        case 0x0D: // data48 / 48-bit data
        case 0x0E: // data56 / 56-bit data
        case 0x1A: // map24 / 24-bit bitmap
        case 0x1C: // map40 / 40-bit bitmap
        case 0x1D: // map48 / 48-bit bitmap
        case 0x1E: // map56 / 56-bit bitmap
        case 0x22: // uint24 / Unsigned 24-bit integer
        case 0x24: // uint40 / Unsigned 40-bit integer
        case 0x25: // uint48 / Unsigned 48-bit integer
        case 0x26: // uint56 / Unsigned 56-bit integer
        case 0x2A: // int24 / Signed 24-bit integer
        case 0x2C: // int40 / Signed 40-bit integer
        case 0x2D: // int48 / Signed 48-bit integer
        case 0x2E: // int56 / Signed 56-bit integer
        case 0x38: // semi / Semi-precision
        case 0x39: // single / Single precision
        case 0x3A: // double / Double precision
        case 0x48: // array / Array
        case 0x49: // struct / Structure
        case 0x50: // set / Set
        case 0x51: // bag / Bag
        case 0xE0: // ToD / Time of day
        {
            ChipLogError(Zcl, "attributeType 0x%02x is not supported", attributeType);
            return true;
        }

        case 0x41: // octstr / Octet string
        case 0x42: // string / Character string
        {
            // Short Strings must contains at least one byte for the length
            CHECK_MESSAGE_LENGTH(1);
            uint8_t length = chip::Encoding::Read8(message);
            ChipLogProgress(Zcl, "  length: 0x%02x", length);

            // When the length is set to 0xFF, it represents a non-value. In this case the data field is zero length.
            if (length == 0xFF)
            {
                length = 0;
            }

            CHECK_MESSAGE_LENGTH(length);
            Callback::Callback<StringAttributeCallback> * cb =
                Callback::Callback<StringAttributeCallback>::FromCancelable(onReportCallback);
            cb->mCall(cb->mContext, chip::ByteSpan(message, length));
            break;
        }

        case 0x43: // octstr16 / Long octet string
        case 0x44: // string16 / Long character string
        {
            // Long Strings must contains at least two bytes for the length
            CHECK_MESSAGE_LENGTH(2);
            uint16_t length = chip::Encoding::LittleEndian::Read16(message);
            ChipLogProgress(Zcl, "  length: 0x%02x", length);

            // When the length is set to 0xFFFF, it represents a non-value. In this case the data field is zero length.
            if (length == 0xFFFF)
            {
                length = 0;
            }

            CHECK_MESSAGE_LENGTH(length);
            Callback::Callback<StringAttributeCallback> * cb =
                Callback::Callback<StringAttributeCallback>::FromCancelable(onReportCallback);
            cb->mCall(cb->mContext, chip::ByteSpan(message, length));
            break;
        }

        case 0x08: // data8 / 8-bit data
        case 0x18: // map8 / 8-bit bitmap
        case 0x20: // uint8 / Unsigned  8-bit integer
        case 0x30: // enum8 / 8-bit enumeration
        {
            CHECK_MESSAGE_LENGTH(1);
            uint8_t value = chip::Encoding::Read8(message);
            ChipLogProgress(Zcl, "  value: 0x%02x", value);

            Callback::Callback<Int8uAttributeCallback> * cb =
                Callback::Callback<Int8uAttributeCallback>::FromCancelable(onReportCallback);
            cb->mCall(cb->mContext, value);
            break;
        }

        case 0x09: // data16 / 16-bit data
        case 0x19: // map16 / 16-bit bitmap
        case 0x21: // uint16 / Unsigned 16-bit integer
        case 0x31: // enum16 / 16-bit enumeration
        case 0xE8: // clusterId / Cluster ID
        case 0xE9: // attribId / Attribute ID
        case 0xEA: // bacOID / BACnet OID
        case 0xF1: // key128 / 128-bit security key
        case 0xFF: // unk / Unknown
        {
            CHECK_MESSAGE_LENGTH(2);
            uint16_t value = chip::Encoding::LittleEndian::Read16(message);
            ChipLogProgress(Zcl, "  value: 0x%04x", value);

            Callback::Callback<Int16uAttributeCallback> * cb =
                Callback::Callback<Int16uAttributeCallback>::FromCancelable(onReportCallback);
            cb->mCall(cb->mContext, value);
            break;
        }

        case 0x0B: // data32 / 32-bit data
        case 0x1B: // map32 / 32-bit bitmap
        case 0x23: // uint32 / Unsigned 32-bit integer
        case 0xE1: // date / Date
        case 0xE2: // UTC / UTCTime
        {
            CHECK_MESSAGE_LENGTH(4);
            uint32_t value = chip::Encoding::LittleEndian::Read32(message);
            ChipLogProgress(Zcl, "  value: 0x%08x", value);

            Callback::Callback<Int32uAttributeCallback> * cb =
                Callback::Callback<Int32uAttributeCallback>::FromCancelable(onReportCallback);
            cb->mCall(cb->mContext, value);
            break;
        }

        case 0x0F: // data64 / 64-bit data
        case 0x1F: // map64 / 64-bit bitmap
        case 0x27: // uint64 / Unsigned 64-bit integer
        case 0xF0: // EUI64 / IEEE address
        {
            CHECK_MESSAGE_LENGTH(8);
            uint64_t value = chip::Encoding::LittleEndian::Read64(message);
            ChipLogProgress(Zcl, "  value: 0x" ChipLogFormatX64, ChipLogValueX64(value));

            Callback::Callback<Int64uAttributeCallback> * cb =
                Callback::Callback<Int64uAttributeCallback>::FromCancelable(onReportCallback);
            cb->mCall(cb->mContext, value);
            break;
        }

        case 0x10: // bool / Boolean
        {
            CHECK_MESSAGE_LENGTH(1);
            uint8_t value = chip::Encoding::Read8(message);
            ChipLogProgress(Zcl, "  value: %d", value);

            Callback::Callback<BooleanAttributeCallback> * cb =
                Callback::Callback<BooleanAttributeCallback>::FromCancelable(onReportCallback);
            cb->mCall(cb->mContext, value);
            break;
        }

        case 0x28: // int8 / Signed 8-bit integer
        {
            CHECK_MESSAGE_LENGTH(1);
            int8_t value = chip::CastToSigned(chip::Encoding::Read8(message));
            ChipLogProgress(Zcl, "  value: %" PRId8, value);

            Callback::Callback<Int8sAttributeCallback> * cb =
                Callback::Callback<Int8sAttributeCallback>::FromCancelable(onReportCallback);
            cb->mCall(cb->mContext, value);
            break;
        }

        case 0x29: // int16 / Signed 16-bit integer
        {
            CHECK_MESSAGE_LENGTH(2);
            int16_t value = chip::CastToSigned(chip::Encoding::LittleEndian::Read16(message));
            ChipLogProgress(Zcl, "  value: %" PRId16, value);

            Callback::Callback<Int16sAttributeCallback> * cb =
                Callback::Callback<Int16sAttributeCallback>::FromCancelable(onReportCallback);
            cb->mCall(cb->mContext, value);
            break;
        }

        case 0x2B: // int32 / Signed 32-bit integer
        {
            CHECK_MESSAGE_LENGTH(4);
            int32_t value = chip::CastToSigned(chip::Encoding::LittleEndian::Read32(message));
            ChipLogProgress(Zcl, "  value: %" PRId32, value);

            Callback::Callback<Int32sAttributeCallback> * cb =
                Callback::Callback<Int32sAttributeCallback>::FromCancelable(onReportCallback);
            cb->mCall(cb->mContext, value);
            break;
        }

        case 0x2F: // int64 / Signed 64-bit integer
        {
            CHECK_MESSAGE_LENGTH(8);
            int64_t value = chip::CastToSigned(chip::Encoding::LittleEndian::Read64(message));
            ChipLogProgress(Zcl, "  value: %" PRId64, value);

            Callback::Callback<Int64sAttributeCallback> * cb =
                Callback::Callback<Int64sAttributeCallback>::FromCancelable(onReportCallback);
            cb->mCall(cb->mContext, value);
            break;
        }
        }
    }

    return true;
}
